﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using CodeMadeSimple.PropertiesManagement;
using System.Text.RegularExpressions;
using log4net;

namespace EnvRide.Core.ObjectModel
{
    /// <summary>
    /// Represents the arguments necessary for the EnvRide processing.
    /// </summary>
    public class EnvRideProcessArguments
    {
        #region Fields

        private XmlDocument _xmlDoc;
        private IPropertyContainer _propContainer;
        private bool _hasErrors = false;
        private String _environmentName;
        private string _propertiesPrefix;
        private string _outputFilePath;
        private bool _saveOutputFileOnlyIfItHasChanges = false;
        private bool _createOutputFileDirectory = false;
        private PropertyNotFoundAction _propertyNotFoundAction = PropertyNotFoundAction.Log;

        #endregion

        #region Properties

        /// <summary>
        /// Indicates if it should create the output file parent directories if it do not exist.
        /// </summary>
        public bool CreateOutputFileDirectory
        {
            get { return _createOutputFileDirectory; }
            set { _createOutputFileDirectory = value; }
        }

        public PropertyNotFoundAction PropertyNotFoundAction 
        {
            get { return _propertyNotFoundAction; }
            set { _propertyNotFoundAction = value; }
        }

        /// <summary>
        /// Indicates if it should only save the to the output file if its has changes.
        /// </summary>
        public bool SaveOutputFileOnlyIfItHasChanges
        {
            get { return _saveOutputFileOnlyIfItHasChanges; }
            set { _saveOutputFileOnlyIfItHasChanges = value; }
        }

        /// <summary>
        /// XmlDocument instance being transformed.
        /// </summary>
        public XmlDocument Document
        {
            get { return _xmlDoc; }
            set { _xmlDoc = value; }
        }

        /// <summary>
        /// Environment to process name.
        /// </summary>
        public String EnvironmentName
        {
            get { return _environmentName; }
            set { _environmentName = value; }
        }

        /// <summary>
        /// Current property context.
        /// </summary>
        public IPropertyContainer PropertyContainer
        {
            get { return _propContainer; }
            set { _propContainer = value; }
        }

        /// <summary>
        /// The prefix prepended to all properties references on the included override(s).
        /// </summary>
        public string PropertiesPrefix
        {
            get { return _propertiesPrefix; }
            set { _propertiesPrefix = value; }
        }

        /// <summary>
        /// Indicates if the process has errors or not.
        /// </summary>
        public bool HasErrors
        {
            get { return _hasErrors; }
            set { _hasErrors = value; }
        }

        /// <summary>
        /// The output file path.
        /// </summary>
        public String OutputFilePath
        {
            get { return _outputFilePath; }
            set { _outputFilePath = value; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Parses the supplied value replacing any properties references with the correct value.
        /// </summary>
        /// <param name="value">Value to parse.</param>
        /// <returns>Parsed value.</returns>
        public String ParseValue(String value)
        {
            if (!String.IsNullOrEmpty(value))
            {
                if (PropertyContainer != null)
                {
                    bool hasErrors = false;

                    value = PropertyContainer.ParseValue(value, PropertiesPrefix, PropertyNotFoundAction, out hasErrors);

                    if (hasErrors)
                    {
                        _hasErrors = true;
                    }
                }
                else
                {
                    EnvRideProject.Logger.Warn("There \"PropertyContainer\" property value is null!");
                }
            }

            return value;
        }

        /// <summary>
        /// Parses the supplied IF expression and returns its boolean value.
        /// </summary>
        /// <param name="ifExp">IF expression to parse.</param>
        /// <returns>Boolean value.</returns>
        public bool ParseIfExpression(String ifExp)
        {
            bool shouldExecute = true;

            if (!String.IsNullOrEmpty(ifExp))
            {
                if (EnvRideProject.Logger.IsDebugEnabled)
                    EnvRideProject.Logger.DebugFormat("Parsing boolean expression \"{0}\"", ifExp);

                ifExp = ParseValue(ifExp);

                //TODO: Implement Csharp runtime
                shouldExecute = Convert.ToBoolean(ifExp);

                if (EnvRideProject.Logger.IsDebugEnabled)
                    EnvRideProject.Logger.DebugFormat("Should execute: {0}", shouldExecute.ToString().ToUpper());
            }

            return shouldExecute;
        }

        #endregion


    }
}
